/**
*     Copyright (c) 2022, Nations Technologies Inc.
* 
*     All rights reserved.
*
*     This software is the exclusive property of Nations Technologies Inc. (Hereinafter 
* referred to as NATIONS). This software, and the product of NATIONS described herein 
* (Hereinafter referred to as the Product) are owned by NATIONS under the laws and treaties
* of the People's Republic of China and other applicable jurisdictions worldwide.
*
*     NATIONS does not grant any license under its patents, copyrights, trademarks, or other 
* intellectual property rights. Names and brands of third party may be mentioned or referred 
* thereto (if any) for identification purposes only.
*
*     NATIONS reserves the right to make changes, corrections, enhancements, modifications, and 
* improvements to this software at any time without notice. Please contact NATIONS and obtain 
* the latest version of this software before placing orders.

*     Although NATIONS has attempted to provide accurate and reliable information, NATIONS assumes 
* no responsibility for the accuracy and reliability of this software.
* 
*     It is the responsibility of the user of this software to properly design, program, and test 
* the functionality and safety of any application made of this information and any resulting product. 
* In no event shall NATIONS be liable for any direct, indirect, incidental, special,exemplary, or 
* consequential damages arising in any way out of the use of this software or the Product.
*
*     NATIONS Products are neither intended nor warranted for usage in systems or equipment, any
* malfunction or failure of which may cause loss of human life, bodily injury or severe property 
* damage. Such applications are deemed, "Insecure Usage".
*
*     All Insecure Usage shall be made at user's risk. User shall indemnify NATIONS and hold NATIONS 
* harmless from and against all claims, costs, damages, and other liabilities, arising from or related 
* to any customer's Insecure Usage.

*     Any express or implied warranty with regard to this software or the Product, including,but not 
* limited to, the warranties of merchantability, fitness for a particular purpose and non-infringement
* are disclaimed to the fullest extent permitted by law.

*     Unless otherwise explicitly permitted by NATIONS, anyone may not duplicate, modify, transcribe
* or otherwise distribute this software for any purposes, in whole or in part.
*
*     NATIONS products and technologies shall not be used for or incorporated into any products or systems
* whose manufacture, use, or sale is prohibited under any applicable domestic or foreign laws or regulations. 
* User shall comply with any applicable export control laws and regulations promulgated and administered by 
* the governments of any countries asserting jurisdiction over the parties or transactions.
**/

/**
*\*\file main.c
*\*\author Nations
*\*\version v1.0.0
*\*\copyright Copyright (c) 2022, Nations Technologies Inc. All rights reserved.
**/
#include "ISR_common.h"
#include "timer_common.h"
#include "ADTIM_common.h"
#include "main.h"

static OCInitType TIM_OCInitStructure;

static TIM_BDTRInitType TIM_BDTRInitStructure;

uint16_t CCR1_Val = 32767;
uint16_t CCR2_Val = 24575;
uint16_t CCR3_Val = 16383;
uint16_t CCR4_Val = 8191;

__IO uint32_t step = 1;

void TIM1_TRG_COM_IRQHandler(void);

void SysTick_Handler(void);

/**
*\*\brief  Configures the SysTick.
**/
void SysTick_Configuration(void)
{
    /* Setup SysTick Timer for 100 msec interrupts  */
    if (SysTick_Config((SystemClockFrequency) / 10))
    {
        /* Capture error */
        while (1)
            ;
    }

    NVIC_SetPriority(SysTick_IRQn, 0x0);
}

int main(void)
{
    Common_ADTIM_RCC_Initialize(TIM1, RCC_HCLK_DIV2);

    Common_ADTIM_GPIO_Initialize(TIM1);
    
    Common_TIM_NVIC_Initialize(TIM1_TRG_COM_IRQn, ENABLE);

    /*
    The n32g430 TIM1 peripheral offers the possibility to program in advance the
    configuration for the next TIM1 outputs behaviour (step) and change the configuration
    of all the channels at the same time. This operation is possible when the COM
    (commutation) event is used.
    The COM event can be generated by software by setting the COM bit in the TIM1_EGR
    register or by hardware (on TRC rising edge).
    In this example, a software COM event is generated each 100 ms: using the Systick
    interrupt.
    The TIM1 is configured in Timing Mode, each time a COM event occurs,
    a new TIM1 configuration will be set in advance.
    The following Table  describes the TIM1 Channels states:
              -----------------------------------------------
             | Step1 | Step2 | Step3 | Step4 | Step5 | Step6 |
    ----------------------------------------------------------
    |Channel1  |   1   |   0   |   0   |   0   |   0   |   1   |
    ----------------------------------------------------------
    |Channel1N |   0   |   0   |   1   |   1   |   0   |   0   |
    ----------------------------------------------------------
    |Channel2  |   0   |   0   |   0   |   1   |   1   |   0   |
    ----------------------------------------------------------
    |Channel2N |   1   |   1   |   0   |   0   |   0   |   0   |
    ----------------------------------------------------------
    |Channel3  |   0   |   1   |   1   |   0   |   0   |   0   |
    ----------------------------------------------------------
    |Channel3N |   0   |   0   |   0   |   0   |   1   |   1   |
    ----------------------------------------------------------
                                                                                    */

    /* TIM Base Init , Period = 4095, prescaler = 0*/                                                                               
    Common_TIM_Base_Initialize(TIM1, 4095, 0);

    SysTick_Configuration();

    TIM_Output_Channel_Struct_Initialize(&TIM_OCInitStructure);

    /* Channel 1, 2 and 3 Configuration in PWM mode */
    TIM_OCInitStructure.OcMode       = TIM_OCMODE_TIMING;
    TIM_OCInitStructure.OutputState  = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.OutputNState = TIM_OUTPUT_NSTATE_ENABLE;
    TIM_OCInitStructure.Pulse        = 2047;
    TIM_OCInitStructure.OcPolarity   = TIM_OC_POLARITY_HIGH;
    TIM_OCInitStructure.OcNPolarity  = TIM_OCN_POLARITY_HIGH;
    TIM_OCInitStructure.OcIdleState  = TIM_OC_IDLE_STATE_SET;
    TIM_OCInitStructure.OcNIdleState = TIM_OCN_IDLE_STATE_SET;
    TIM_Output_Channel1_Initialize(TIM1, &TIM_OCInitStructure);

    TIM_OCInitStructure.Pulse = 1023;
    TIM_Output_Channel2_Initialize(TIM1, &TIM_OCInitStructure);

    TIM_OCInitStructure.Pulse = 511;
    TIM_Output_Channel3_Initialize(TIM1, &TIM_OCInitStructure);


    /* Automatic Output enable, Break, dead time and lock configuration*/
    TIM_Break_And_Dead_Time_Struct_Initialize(&TIM_BDTRInitStructure);
    
    TIM_BDTRInitStructure.OssrState       = TIM_OSSR_STATE_ENABLE;
    TIM_BDTRInitStructure.OssiState       = TIM_OSSI_STATE_ENABLE;
    TIM_BDTRInitStructure.LockLevel       = TIM_LOCK_LEVEL_OFF;
    TIM_BDTRInitStructure.DeadTime        = 1;
    TIM_BDTRInitStructure.Break           = TIM_BREAK_IN_DISABLE;
    TIM_BDTRInitStructure.BreakPolarity   = TIM_BREAK_POLARITY_HIGH;
    TIM_BDTRInitStructure.AutomaticOutput = TIM_AUTO_OUTPUT_ENABLE;

    TIM_Break_And_Dead_Time_Set(TIM1, &TIM_BDTRInitStructure);

    TIM_Capture_Compare_Control_Preload_Enable(TIM1);
    TIM_Interrupt_Enable(TIM1, TIM_INT_COM);

    TIM_On(TIM1);
    
    TIM_PWM_Output_Enable(TIM1);

    while(1)
    {

    }
}

/******************************************************************************/
/*            n32g430 Peripherals Interrupt Handlers                        */
/******************************************************************************/

/**
*\*\brief  This function handles TIM1 Break Update Trigger and commutation interrupts
*\*\       requests.
**/
void TIM1_TRG_COM_IRQHandler(void)
{
    if(TIM_Flag_Status_Get(TIM1, TIM_FLAG_COM))
    {
        /* Clear TIM1 COM pending bit */
        TIM_Interrupt_Status_Clear(TIM1, TIM_INT_COM);
    }
    else
    {
        return;
    }

    if (step == 1)
    {
        /* Next step: Step 2 Configuration ---------------------------- */
        /*  Channel3 configuration */
        TIM_Capture_Compare_Ch_Disable(TIM1, TIM_CH_3);
        TIM_Capture_Compare_Ch_N_Disable(TIM1, TIM_CH_3);

        /*  Channel1 configuration */
        TIM_Output_Channel_Mode_Set(TIM1, TIM_OCMODE_PWM1, TIM_CH_1);
        TIM_Capture_Compare_Ch_Enable(TIM1, TIM_CH_1);
        TIM_Capture_Compare_Ch_N_Disable(TIM1, TIM_CH_1);

        /*  Channel2 configuration */
        TIM_Output_Channel_Mode_Set(TIM1, TIM_OCMODE_PWM1, TIM_CH_2);
        TIM_Capture_Compare_Ch_Disable(TIM1, TIM_CH_2);
        TIM_Capture_Compare_Ch_N_Enable(TIM1, TIM_CH_2);
        step++;
    }
    else if (step == 2)
    {
        /* Next step: Step 3 Configuration ---------------------------- */
        /*  Channel2 configuration */
        TIM_Output_Channel_Mode_Set(TIM1, TIM_OCMODE_PWM1, TIM_CH_2);
        TIM_Capture_Compare_Ch_Disable(TIM1, TIM_CH_2);
        TIM_Capture_Compare_Ch_N_Enable(TIM1, TIM_CH_2);

        /*  Channel3 configuration */
        TIM_Output_Channel_Mode_Set(TIM1, TIM_OCMODE_PWM1, TIM_CH_3);
        TIM_Capture_Compare_Ch_Enable(TIM1, TIM_CH_3);
        TIM_Capture_Compare_Ch_N_Disable(TIM1, TIM_CH_3);

        /*  Channel1 configuration */
        TIM_Capture_Compare_Ch_Disable(TIM1, TIM_CH_1);
        TIM_Capture_Compare_Ch_N_Disable(TIM1, TIM_CH_1);
        step++;
    }
    else if (step == 3)
    {
        /* Next step: Step 4 Configuration ---------------------------- */
        /*  Channel3 configuration */
        TIM_Output_Channel_Mode_Set(TIM1, TIM_OCMODE_PWM1, TIM_CH_3);
        TIM_Capture_Compare_Ch_Enable(TIM1, TIM_CH_3);
        TIM_Capture_Compare_Ch_N_Disable(TIM1, TIM_CH_3);

        /*  Channel2 configuration */
        TIM_Capture_Compare_Ch_Disable(TIM1, TIM_CH_2);
        TIM_Capture_Compare_Ch_N_Disable(TIM1, TIM_CH_2);

        /*  Channel1 configuration */
        TIM_Output_Channel_Mode_Set(TIM1, TIM_OCMODE_PWM1, TIM_CH_1);
        TIM_Capture_Compare_Ch_Disable(TIM1, TIM_CH_1);
        TIM_Capture_Compare_Ch_N_Enable(TIM1, TIM_CH_1);
        step++;
    }
    else if (step == 4)
    {
        /* Next step: Step 5 Configuration ---------------------------- */
        /*  Channel3 configuration */
        TIM_Capture_Compare_Ch_Disable(TIM1, TIM_CH_3);
        TIM_Capture_Compare_Ch_N_Disable(TIM1, TIM_CH_3);

        /*  Channel1 configuration */
        TIM_Output_Channel_Mode_Set(TIM1, TIM_OCMODE_PWM1, TIM_CH_1);
        TIM_Capture_Compare_Ch_Disable(TIM1, TIM_CH_1);
        TIM_Capture_Compare_Ch_N_Enable(TIM1, TIM_CH_1);

        /*  Channel2 configuration */
        TIM_Output_Channel_Mode_Set(TIM1, TIM_OCMODE_PWM1, TIM_CH_2);
        TIM_Capture_Compare_Ch_Enable(TIM1, TIM_CH_2);
        TIM_Capture_Compare_Ch_N_Disable(TIM1, TIM_CH_2);
        step++;
    }
    else if (step == 5)
    {
        /* Next step: Step 6 Configuration ---------------------------- */
        /*  Channel3 configuration */
        TIM_Output_Channel_Mode_Set(TIM1, TIM_OCMODE_PWM1, TIM_CH_3);
        TIM_Capture_Compare_Ch_Disable(TIM1, TIM_CH_3);
        TIM_Capture_Compare_Ch_N_Enable(TIM1, TIM_CH_3);

        /*  Channel1 configuration */
        TIM_Capture_Compare_Ch_Disable(TIM1, TIM_CH_1);
        TIM_Capture_Compare_Ch_N_Disable(TIM1, TIM_CH_1);

        /*  Channel2 configuration */
        TIM_Output_Channel_Mode_Set(TIM1, TIM_OCMODE_PWM1, TIM_CH_2);
        TIM_Capture_Compare_Ch_Enable(TIM1, TIM_CH_2);
        TIM_Capture_Compare_Ch_N_Disable(TIM1, TIM_CH_2);
        step++;
    }
    else
    {
        /* Next step: Step 1 Configuration ---------------------------- */
        /*  Channel1 configuration */
        TIM_Output_Channel_Mode_Set(TIM1, TIM_OCMODE_PWM1, TIM_CH_1);
        TIM_Capture_Compare_Ch_Enable(TIM1, TIM_CH_1);
        TIM_Capture_Compare_Ch_N_Disable(TIM1, TIM_CH_2);

        /*  Channel3 configuration */
        TIM_Output_Channel_Mode_Set(TIM1, TIM_OCMODE_PWM1, TIM_CH_3);
        TIM_Capture_Compare_Ch_Disable(TIM1, TIM_CH_3);
        TIM_Capture_Compare_Ch_N_Enable(TIM1, TIM_CH_3);

        /*  Channel2 configuration */
        TIM_Capture_Compare_Ch_Disable(TIM1, TIM_CH_2);
        TIM_Capture_Compare_Ch_N_Disable(TIM1, TIM_CH_2);
        step = 1;
    }
}

/**
*\*\brief  This function handles SysTick Handler.
**/
void SysTick_Handler(void)
{
    /* Generate TIM1 COM event by software */
    TIM_Event_Generate(TIM1, TIM_EVT_SRC_COM);
}
